﻿using Kaskelot.SP.Core;
using Kaskelot.SP.Model.Client;
using Kaskelot.SP.Model.Client.Forms;
using Kaskelot.SP.Services.Client.Mapping;
using Microsoft.SharePoint;
using Stockholm.SOA.Kaskelot.WCF.DataContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace Kaskelot.SP.Services.Client
{
	[ServiceContract(Namespace = "http://Kaskelot.SP.Services")]
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public class ClientAdminService
	{
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientValkrets>> GetValkretsar()
		{
			ClientServiceResult<IEnumerable<ClientValkrets>> csr = new ClientServiceResult<IEnumerable<ClientValkrets>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					IList<Valkrets> valkretsar = svc.GetValkretsar();

					csr.Data = valkretsar.Select(vk => vk.ToClientContract()).OrderBy(vk => vk.ValkretsNr);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<string>> DeleteValkrets(ValkretsForm form)
		{
			ClientServiceResult<IEnumerable<string>> csr = new ClientServiceResult<IEnumerable<string>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteValkrets(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Valkretsen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateValkrets(ValkretsForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Valkrets valkrets = new Valkrets()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateValkrets(valkrets.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateValkrets(ValkretsForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Valkrets valkrets = svc.GetValkrets(new Guid(form.Id));
					svc.UpdateValkrets(valkrets.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientForsamling>> GetForsamlingar(string valkretsId)
		{
			ClientServiceResult<IEnumerable<ClientForsamling>> csr = new ClientServiceResult<IEnumerable<ClientForsamling>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					IList<Forsamling> forsamlingar = null;
					if (String.IsNullOrEmpty(valkretsId))
						forsamlingar = svc.GetForsamlingar(null);
					else
						forsamlingar = svc.GetForsamlingar(new Guid(valkretsId));

					IList<ClientForsamling> result = new List<ClientForsamling>();

					foreach (Forsamling f in forsamlingar)
					{
						result.Add(new ClientForsamling() { Id = f.Id.ToString(), Namn = f.Namn, ValkretsNamn = f.Valkrets.Namn, ForsamlingNr = f.ForsamlingNr, ValkretsNr = f.Valkrets.ValkretsNr });
					}

					csr.Data = result.OrderBy(f => f.ValkretsNr).ThenBy(f => f.ForsamlingNr);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<string>> DeleteForsamling(ForsamlingForm form)
		{
			ClientServiceResult<IEnumerable<string>> csr = new ClientServiceResult<IEnumerable<string>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteForsamling(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Församlingen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateForsamling(ForsamlingForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Forsamling forsamling = new Forsamling()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateForsamling(forsamling.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateForsamling(ForsamlingForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Forsamling forsamling = svc.GetForsamling(new Guid(form.Id));
					svc.UpdateForsamling(forsamling.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientValdistrikt>> GetValdistriktList(string forsamlingId)
		{
			ClientServiceResult<IEnumerable<ClientValdistrikt>> csr = new ClientServiceResult<IEnumerable<ClientValdistrikt>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					IList<Valdistrikt> valdistrikt = null;
					if (String.IsNullOrEmpty(forsamlingId))
						valdistrikt = svc.GetValdistriktList(null);
					else
						valdistrikt = svc.GetValdistriktList(new Guid(forsamlingId));

					IList<ClientValdistrikt> result = new List<ClientValdistrikt>();

					foreach (Valdistrikt v in valdistrikt)
					{
						result.Add(new ClientValdistrikt() { Id = v.Id, Namn = v.Namn, ForsamlingNamn = v.ForsamlingNamn, ValdistriktNr = v.ValdistriktNr });
					}

					csr.Data = result.OrderBy(v => v.ForsamlingNamn).ThenBy(v => v.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<string>> DeleteValdistrikt(ValdistriktForm form)
		{
			ClientServiceResult<IEnumerable<string>> csr = new ClientServiceResult<IEnumerable<string>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteValdistrikt(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Valdistriktet gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateValdistrikt(ValdistriktForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					if (!form.ForsamlingId.IsGuid())
						throw new ApplicationException("Ingen församling vald");

					Valdistrikt valdistrikt = new Valdistrikt()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};
					valdistrikt.UpdateContract(form);

					var existingValdistrikt = svc.GetValdistriktList(new Guid(form.ForsamlingId));
					bool exists = existingValdistrikt.Where(v => v.ValdistriktNr == valdistrikt.ValdistriktNr).Count() > 0;
					
					if(!exists)
						svc.CreateValdistrikt(valdistrikt);
					else
						throw new ApplicationException("Ett valdistrikt med nummer " + valdistrikt.ValdistriktNr + " finns redan.");
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateValdistrikt(ValdistriktForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					if (!form.ForsamlingId.IsGuid())
						throw new ApplicationException("Ingen församling vald");

					Valdistrikt valdistrikt = svc.GetValdistrikt(new Guid(form.Id));
					svc.UpdateValdistrikt(valdistrikt.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientMaterielTyp>> GetMaterielTypList()
		{
			ClientServiceResult<IEnumerable<ClientMaterielTyp>> csr = new ClientServiceResult<IEnumerable<ClientMaterielTyp>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					IList<MaterielTyp> materieltyper = svc.GetMaterielTypList();

					IList<ClientMaterielTyp> result = new List<ClientMaterielTyp>();

					foreach (MaterielTyp mt in materieltyper)
					{
						IEnumerable<MaterielTyp> underliggande = svc.GetUnderliggandeMaterielTyperForMaterielTyp(mt.Id);

						string s = String.Empty;

						foreach (MaterielTyp ul in underliggande)
						{
							if (!String.IsNullOrEmpty(s))
								s += ", ";

							s += ul.Beskrivning;
						}

						result.Add(new ClientMaterielTyp
						{
							Beskrivning = mt.Beskrivning,
							Id = mt.Id,
							UnderliggandeMateriel = s,
							VisaILista = mt.VisaILista.ToJaNej()
						});
					}

					csr.Data = result.OrderBy(b => b.VisaILista).ThenBy(b => b.Beskrivning);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<string>> DeleteMaterielTyp(MaterielTypForm form)
		{
			ClientServiceResult<IEnumerable<string>> csr = new ClientServiceResult<IEnumerable<string>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteMaterielTyp(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Materieltypen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateMaterielTyp(MaterielTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					if (form.Beskrivning.Length > 190)
						throw new ApplicationException("Beskrivningen är för lång.");

					MaterielTyp materieltyp = new MaterielTyp()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateMaterielTyp(materieltyp.UpdateContract(form));

					IList<MaterielTypMaterielTyp> mtmtList = new List<MaterielTypMaterielTyp>();

					foreach (string id in form.ChildIdList)
					{
						MaterielTypMaterielTyp mtmt = new MaterielTypMaterielTyp
						{
							Id = Guid.NewGuid(),
							ValId = materieltyp.ValId,
							SkapadAv = SPContext.Current.Web.CurrentUser.Name,
							Skapad = DateTime.Now,
							ParentId = materieltyp.Id,
							ChildId = new Guid(id)
						};

						mtmtList.Add(mtmt);
					}

					svc.SetUnderliggandeMaterielTyperForMaterielTyp(materieltyp.Id, mtmtList);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateMaterielTyp(MaterielTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					if (form.Beskrivning.Length > 190)
						throw new ApplicationException("Beskrivningen är för lång.");

					MaterielTyp materieltyp = svc.GetMaterielTyp(new Guid(form.Id));
					svc.UpdateMaterielTyp(materieltyp.UpdateContract(form));

					IList<MaterielTypMaterielTyp> mtmtList = new List<MaterielTypMaterielTyp>();

					foreach (string id in form.ChildIdList)
					{
						MaterielTypMaterielTyp mtmt = new MaterielTypMaterielTyp
						{
							Id = Guid.NewGuid(),
							ValId = materieltyp.ValId,
							SkapadAv = SPContext.Current.Web.CurrentUser.Name,
							Skapad = DateTime.Now,
							ParentId = materieltyp.Id,
							ChildId = new Guid(id),
						};

						mtmtList.Add(mtmt);
					}

					svc.SetUnderliggandeMaterielTyperForMaterielTyp(materieltyp.Id, mtmtList);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientFunktion>> GetFunktioner()
		{
			ClientServiceResult<IEnumerable<ClientFunktion>> csr = new ClientServiceResult<IEnumerable<ClientFunktion>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GetFunktioner().Select(f => f.ToClientContract()).OrderBy(f => f.Beskrivning);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<string>> DeleteFunktion(FunktionForm form)
		{
			ClientServiceResult<IEnumerable<string>> csr = new ClientServiceResult<IEnumerable<string>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteFunktion(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Funktionen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateFunktion(FunktionForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Funktion funktion = new Funktion()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateFunktion(funktion.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateFunktion(FunktionForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Funktion funktion = svc.GetFunktion(new Guid(form.Id));
					svc.UpdateFunktion(funktion.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientGrupp>> GruppSearch()
		{
			ClientServiceResult<IEnumerable<ClientGrupp>> csr = new ClientServiceResult<IEnumerable<ClientGrupp>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GruppSearch().Select(g => g.ToClientContract()).OrderBy(g => g.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteGrupp(GruppForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteGrupp(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Gruppen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateGrupp(GruppForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Grupp grupp = new Grupp()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateGrupp(grupp.UpdateContract(form));

					using (BemanningService bSvc = new BemanningService())
					{
						int antal = -1;
						if (form.FunktionId.IsGuid() && Int32.TryParse(form.Antal, out antal))
						{
							for (int i = 0; i < antal; i++)
							{
								BemanningGrupp bv = new BemanningGrupp
								{
									SkapadAv = SPContext.Current.Web.CurrentUser.Name,
									Skapad = DateTime.Now,
									ValId = ApplicationContext.Current.Val.Id,
									Id = Guid.NewGuid()
								};

								bv.FunktionId = new Guid(form.FunktionId);
								bv.GruppId = grupp.Id;
								bSvc.CreateBemanningGrupp(bv);
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateGrupp(GruppForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Grupp grupp = svc.GetGrupp(new Guid(form.Id));
					svc.UpdateGrupp(grupp.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientPersonTyp>> GetPersonTyper()
		{
			ClientServiceResult<IEnumerable<ClientPersonTyp>> csr = new ClientServiceResult<IEnumerable<ClientPersonTyp>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GetPersonTyper().Select(g => g.ToClientContract()).OrderBy(g => g.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeletePersonTyp(PersonTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeletePersonTyp(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "PersonTypen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreatePersonTyp(PersonTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					PersonTyp PersonTyp = new PersonTyp()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreatePersonTyp(PersonTyp.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdatePersonTyp(PersonTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					PersonTyp PersonTyp = svc.GetPersonTyp(new Guid(form.Id));
					svc.UpdatePersonTyp(PersonTyp.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientByggnadTyp>> GetByggnadTyper()
		{
			ClientServiceResult<IEnumerable<ClientByggnadTyp>> csr = new ClientServiceResult<IEnumerable<ClientByggnadTyp>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GetByggnadTyper().Select(g => g.ToClientContract()).OrderBy(g => g.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteByggnadTyp(ByggnadTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteByggnadTyp(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "ByggnadTypen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateByggnadTyp(ByggnadTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					ByggnadTyp byggnadtyp = new ByggnadTyp()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateByggnadTyp(byggnadtyp.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateByggnadTyp(ByggnadTypForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					ByggnadTyp ByggnadTyp = svc.GetByggnadTyp(new Guid(form.Id));
					svc.UpdateByggnadTyp(ByggnadTyp.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientStadsdel>> GetStadsdelar()
		{
			ClientServiceResult<IEnumerable<ClientStadsdel>> csr = new ClientServiceResult<IEnumerable<ClientStadsdel>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GetStadsdelar().Select(g => g.ToClientContract()).OrderBy(g => g.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteStadsdel(StadsdelForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteStadsdel(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Stadsdelen gick inte att ta bort.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateStadsdel(StadsdelForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Stadsdel stadsdel = new Stadsdel()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateStadsdel(stadsdel.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateStadsdel(StadsdelForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Stadsdel stadsdel = svc.GetStadsdel(new Guid(form.Id));
					svc.UpdateStadsdel(stadsdel.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientVal>> GetAllVal()
		{
			ClientServiceResult<IEnumerable<ClientVal>> csr = new ClientServiceResult<IEnumerable<ClientVal>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GetAllVal().Select(x => x.ToClientContract()).OrderByDescending(x => x.ValDatum).ThenBy(x => x.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateVal(ValForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Val val = svc.GetVal(new Guid(form.Id));
					svc.UpdateVal(val.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateVal(ValForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					if (!form.Id.IsGuid())
						throw new ApplicationException("Kunde inte skapa val.");

					Val v = new Val()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now
					};
					v.UpdateContract(form);
					v.Aktivt = true;
					svc.CreateVal(v, new Guid(form.Id));

					DocumentService docSvc = new DocumentService();
					Val oldVal = svc.GetVal(new Guid(form.Id));
					docSvc.CopyFolderContents(SPContext.Current.Site, oldVal, v);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> SetActive(string id)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				ApplicationContext.Current.SetCurrentVal(new Guid(id));
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientBlankett>> GetBlanketter()
		{
			ClientServiceResult<IEnumerable<ClientBlankett>> csr = new ClientServiceResult<IEnumerable<ClientBlankett>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GetBlanketter().Select(g => g.ToClientContract()).OrderBy(g => g.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteBlankett(BlankettForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteBlankett(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Blanketten gick inte att ta bort. Kom ihåg att du måste ta bort alla fält från blanketten innan du kan ta bort själva blanketten.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateBlankett(BlankettForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Blankett blankett = new Blankett()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};

					blankett = blankett.UpdateContract(form);

					// Try to get any existing blankett with the same name
					Blankett existingBlankett = svc.GetBlankettByName(blankett.Namn);
					if (existingBlankett != null)
					{
						csr.ErrorMessage = "En blankett finns redan med det namnet";
						csr.HasError = true;
						return csr;
					}

					svc.CreateBlankett(blankett);

					IList<BlankettFalt> blankettFaltList = new List<BlankettFalt>();

					if (form.ChildIdList != null)
					{
						int i = 0;
						foreach (string id in form.ChildIdList)
						{
							BlankettFalt blankettFalt = new BlankettFalt
							{
								Id = Guid.NewGuid(),
								ValId = blankett.ValId,
								BlankettId = blankett.Id,
								FaltId = new Guid(id),
								RadIndex = i
							};

							blankettFaltList.Add(blankettFalt);
							i++;
						}
					}
					svc.SetFaltForBlankett(blankett.Id, blankettFaltList);
					csr.ErrorMessage = "Called SetFaltForBlankett with " + blankettFaltList.Count + " children. ValId: " + blankett.ValId + " , BlankettId: " + blankett.Id + " , blankettFaltList: " + blankettFaltList.ToString();
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateBlankett(BlankettForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Blankett blankett = svc.GetBlankett(new Guid(form.Id));
					svc.UpdateBlankett(blankett.UpdateContract(form));

					IList<BlankettFalt> blankettFaltList = new List<BlankettFalt>();

					if (form.ChildIdList != null)
					{
						int i = 0;
						foreach (string id in form.ChildIdList)
						{
							BlankettFalt blankettFalt = new BlankettFalt
							{
								Id = Guid.NewGuid(),
								ValId = blankett.ValId,
								BlankettId = blankett.Id,
								FaltId = new Guid(id),
								RadIndex = i
							};

							blankettFaltList.Add(blankettFalt);
							i++;
						}
					}

					svc.SetFaltForBlankett(blankett.Id, blankettFaltList);
					csr.ErrorMessage = "Called SetFaltForBlankett with " + blankettFaltList.Count + " children. ValId: " + blankett.ValId + " , BlankettId: " + blankett.Id + " , blankettFaltList: " + blankettFaltList.ToString();
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientFalt>> GetAllaFalt()
		{
			ClientServiceResult<IEnumerable<ClientFalt>> csr = new ClientServiceResult<IEnumerable<ClientFalt>>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					csr.Data = svc.GetAllaFalt().Select(g => g.ToClientContract()).OrderBy(g => g.Namn);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteFalt(FaltForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					svc.DeleteFalt(new Guid(form.Id));
				}
			}
			catch (ApplicationException ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}
			catch (Exception)
			{
				csr.ErrorMessage = "Fältet gick inte att ta bort. Verifiera att fältet inte används på någon blankett och att alla fältalternativ är borttagna.";
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreateFalt(FaltForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Falt falt = new Falt()
					{
						ValId = ApplicationContext.Current.Val.Id
					};

					svc.CreateFalt(falt.UpdateContract(form));

					if (!string.IsNullOrEmpty(form.FaltAlternativ))
					{
						string[] listaAvAlternativ = form.FaltAlternativ.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
						IList<FaltAlternativ> allaFaltAlternativ = new List<FaltAlternativ>();

						foreach (string alternativ in listaAvAlternativ)
						{
							FaltAlternativ faltAlternativ = new FaltAlternativ
							{
								Id = Guid.NewGuid(),
								ValId = falt.ValId,
								FaltId = falt.Id,
								Namn = alternativ
							};

							allaFaltAlternativ.Add(faltAlternativ);
						}
						svc.SetFaltAlternativForFalt(falt.Id, allaFaltAlternativ);
					}
					else
						svc.SetFaltAlternativForFalt(falt.Id, new List<FaltAlternativ>());
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdateFalt(FaltForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (AdminService svc = new AdminService())
				{
					Falt falt = svc.GetFalt(new Guid(form.Id));
					svc.UpdateFalt(falt.UpdateContract(form));

					if (!string.IsNullOrEmpty(form.FaltAlternativ))
					{
						string[] listaAvAlternativ = form.FaltAlternativ.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
						IList<FaltAlternativ> allaFaltAlternativ = new List<FaltAlternativ>();

						foreach (string alternativ in listaAvAlternativ)
						{
							FaltAlternativ faltAlternativ = new FaltAlternativ
							{
								Id = Guid.NewGuid(),
								ValId = falt.ValId,
								FaltId = falt.Id,
								Namn = alternativ
							};

							allaFaltAlternativ.Add(faltAlternativ);
						}
						svc.SetFaltAlternativForFalt(falt.Id, allaFaltAlternativ);
					}
					else
						svc.SetFaltAlternativForFalt(falt.Id, new List<FaltAlternativ>());
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientDokument>> GetTemplates()
		{
			ClientServiceResult<IEnumerable<ClientDokument>> csr = new ClientServiceResult<IEnumerable<ClientDokument>>();

			try
			{
				DocumentService svc = new DocumentService();
				csr.Data = svc.GetTemplates(SPContext.Current.Site).Select(d => d.ToClientContract()).ToList();
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeleteTemplate(string dokumentId)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				if (!ApplicationContext.Current.Val.Aktivt)
					throw new ApplicationException("Valet är låst och kan inte redigeras.");

				int dokId = 0;
				if (int.TryParse(dokumentId, out dokId))
				{
					DocumentService docSvc = new DocumentService();
					docSvc.DeleteTemplate(SPContext.Current.Site, dokId);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}
	}
}
